|
|
"Warp" <war### [at] tagpovrayorg> wrote:
>
> The compiler will always generate a shift opcode for integer/2,
> regardless of whether 'integer' is signed or unsigned. Processors
> have two kinds of shift right opcode for this.
> IIRC, this applies to integer>>1 as well. Thus they are
> completely equivalent.
Well, they are *not* equivalent.
The thing is that -1/2 ("minus one divided by two") is 0, while -1>>1
("minus one shifted right by one") is still -1. That's that problem that
compilers have to resolve somehow. One of the solutions is to add 1 to
negative numbers right before the shift, so truly equivalent code would look
like this:
n / 2 <==> (n >= 0? n: n + 1) >> 1
These two expressions yield equivalent results, indeed. Of course, any
comparisons would be way too expensive to be used in practice...
Fortunately, most instruction sets have some tricks/workarounds for the
problem. For instance, here is what an x86 32-bit back-end generates for a
signed integer division by 2 of the operand loaded into 'eax':
cdq
sub eax, edx
sar eax, 1
The first instruction fills 'edx' with -1 if 'eax' is negative, or with 0
otherwise. Therefore, the second instruction adds 1 in the former case, or
does nothing in the latter. Finally, the third instruction does the division
by 2 itself.
Post a reply to this message
|
|